package com.hzlj.position.locate.differentiation.sysCheck.traceCheck.cross;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.hzlj.common.message.common.dto.message.MessageNoticeResultDTO;
import com.hzlj.position.locate.common.common.PositionSimpleDTO;
import com.hzlj.position.locate.common.dto.position.PositionExtDTO;
import com.hzlj.position.locate.common.dto.position.PositionQueryResultDTO;
import com.hzlj.position.locate.common.enums.DifferentiationDataType;
import com.hzlj.position.locate.common.model.Position;
import com.hzlj.position.locate.differentiation.DifferentiationService;
import com.hzlj.position.locate.differentiation.sysCheck.traceCheck.TraceSysCheck;
import com.hzlj.position.locate.service.DifferentiationConfigService;
import com.hzlj.position.locate.service.MessageTemplateBussService;
import com.hzlj.position.locate.service.PositionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.hzlj.position.locate.common.enums.DifferentiationDataType.SC_CROSS;

/**
 * 越界分流
 */
@Slf4j
@Service
public class CrossSysCheck implements TraceSysCheck, DifferentiationService, MessageTemplateBussService {
    @Resource
    private DifferentiationConfigService config;
    @Resource
    private PositionService positionService;

    @Override
    public DifferentiationDataType getType() {
        return SC_CROSS;
    }


    /**
     * 第一步：通知矫正对象上报
     */
    public void noticeJzry(List<Position> positions,
                           Map<String, MessageNoticeResultDTO> notices) {
        //分组
        Map<DifferentiationService, List<Position>> positionsByService = positions.stream()
                .filter(e -> config.getService(this, getType(), e.getJgCode()) != null)
                .collect(Collectors.groupingBy(e -> config.getService(this, getType(), e.getJgCode())));
        //通知
        positionsByService.forEach((k, v) -> {
            List<Position> filterPositions = ((TraceSysCheck) k).filterPosition(positions);
            if (ObjectUtil.isEmpty(filterPositions)) {
                return;
            }
            log.info("[位置确认]需要发起位置上报:service={},originPositionIds={}",
                    k.getClass().getSimpleName(), positions.stream().map(Position::getId).collect(Collectors.toList()));
            ((TraceSysCheck) k).noticeJzry(filterPositions, notices);
        });
    }


    /**
     * 第二步：矫正对象是上报
     */
    public void updateReportResult(String jzId,
                                   String jgCode,
                                   PositionSimpleDTO report,
                                   PositionSimpleDTO originPosition) {
        DifferentiationService service = config.getService(this, getType(), jgCode);
        if (service == null) {
            return;
        }
        log.info("[位置确认]收到位置上报记录:service={},reportPositionId={},originPositionId={}",
                service.getClass().getSimpleName(), report.getId(), originPosition.getId());
        ((TraceSysCheck) service).updateReportResult(jzId, jgCode, report, originPosition);
    }


    /**
     * 第三步：发送未上报结果
     */
    public void updateNoticeResult(String messageTemplate,
                                   String serviceId,
                                   Date belongDay,
                                   Map<String, Object> checkParams,
                                   MessageNoticeResultDTO notice) {
        if (!messageTemplate.startsWith("locate-sys-check-no-report-")) {
            return;
        }
        DateTime positionTime = DateUtil.parseDateTime((String) checkParams.get("positionTime"));
        PositionQueryResultDTO position = this.positionService.getPosition(serviceId, positionTime);
        //运营商的越界记录
        DifferentiationService service = config.getService(this, getType(), position.getJgCode());
        if (service == null) {
            return;
        }

        log.info("[位置确认]超时未上报:service={},originPositionId={}，notice={}",
                service.getClass().getSimpleName(), serviceId, notice);

        ((TraceSysCheck) service).updateNoReportResult(position, notice);
    }

    public void updateNoReportResult(PositionQueryResultDTO position,
                                     MessageNoticeResultDTO notice) {
    }

    @Override
    public boolean checkNeedSend(String messageTemplate,
                                 String serviceId,
                                 Date belongDay,
                                 Map<String, Object> messageParams,
                                 Map<String, Object> checkParams) {
        DateTime positionTime = DateUtil.parseDateTime((String) checkParams.get("positionTime"));
        PositionExtDTO positionExt = this.positionService.getPositionExt(serviceId, positionTime);
        //已经上报
        if (positionExt != null
                && positionExt.getTrackCheckReportPosition() != null) {
            log.info("[位置确认]矫正对象已经上报，不需要做超时未上报:originPositionId={}，message={}", serviceId, messageParams);
            return false;
        }
        return true;
    }


    public List<Position> filterPosition(List<Position> positions) {
        return positions;
    }

}
